package model;

import java.util.Comparator;
import java.util.EnumSet;
import java.util.Set;

/**
 * @author Alex Vikharev alex.vikharev@gmail.com
 *         created 25.01.12
 */
public final class Position {
    private static final Comparator<Position> COMPARATOR = new Comparator<Position>() {
        @Override
        public int compare(Position o1, Position o2) {
            int result = Field.comparator().compare(o1.field, o2.field);
            if (result != 0) {
                return result;
            } else {
                int code1 = o1.getFigure() == null ? -1 : o1.getFigure().code;
                int code2 = o2.getFigure() == null ? -1 : o2.getFigure().code;
                if (code1 != code2) {
                    return code1 - code2;
                }
            }
            return 0;
        }
    };

    private final Field field;
    private final Figure figure;

    public Position(Field field, Figure figure) {
        if (field == null) {
            throw new NullPointerException("Field must not be null");
        }
        this.field = field;
        this.figure = figure;
    }

    public Field getField() {
        return field;
    }

    public Figure getFigure() {
        return figure;
    }

    public static boolean isMoveValid(Field oldField, Figure givenFigure, Field newField, Figure newFigure, final GameType gameType) {
        Set<Figure> diff = EnumSet.copyOf(newField.getUsedFigures());
        diff.removeAll(oldField.getUsedFigures());
        return (newField.getUsedFigures().size() - oldField.getUsedFigures().size() == 1 &&
                diff.size() == 1 && diff.contains(givenFigure)) &&
                (newField.getUsedFigures().size() == 16 || newField.isGameOver(gameType) || !newField.getUsedFigures().contains(newFigure));
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Position move = (Position) o;

        if (!field.equals(move.field)) return false;
        if (figure != move.figure) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = field.hashCode();
        result = 31 * result + (figure != null ? figure.hashCode() : 0);
        return result;
    }

    public static Comparator<Position> comparator() {
        return COMPARATOR;
    }

    @Override
    public String toString() {
        return "Field: \n" + field +
                "\nFigure=" + (figure == null ? "none" : figure.code);
    }
}
